/**
 * 假设： 我们需要在 vue的 路由文件中插入指定的内容
 *
 * {
    path: "/addNewUserLog",
    name: "addNewsUserLogName",
    meta: {
      title: "新增的节点",
      hidden: false
    },
    component: () => import("@/views/log-manage/add-new-user-log")
  }
 */

import generate from '@babel/generator'
import { parse } from '@babel/parser'
import traverse from '@babel/traverse'
import * as types from '@babel/types'

import fs from 'node:fs'
import path from 'node:path'

const target = path.resolve(__dirname, '../demo/06.js')

const content = fs.readFileSync(target, {
	encoding: 'utf-8',
})

let ast = parse(content, {
	sourceType: 'module',
})

traverse(ast, {
	/**
	 * 通过 https://astexplorer.net/ 我们要插入的内容在 path: '/logManage', 的子节点， children
	 * 对应的节点类型叫  ObjectProperty
	 */
	ObjectProperty(path) {
		insertNode(path)
	},
})

/**
 * 插入节点信息
 */
function insertNode(path) {
	const node = path.node
	const key = path.node.key

	// 首先需要手动推断，当前节点为 对象属性，不然下面的操作ts都会报类型错误
	// 然后我们要操作对象里面的key，取信息，需要判断key为一个 Identifier 类型的Node 节点
	if (types.isObjectProperty(node) && types.isIdentifier(key)) {
		const value = node.value

		if (types.isStringLiteral(value)) {
			// 属性节点
			if (key.name === 'path' && value.value === '/logManage') {
				// 找到父节点，然后插入期望的代码

				// 在 ts中需要对类型做断言，否则访问属性会报错，一种是使用方法，一种是使用 as, 都可以
				// if (types.isObjectExpression(path.parent)) {
				//   let p =path.parent.properties as Array<types.ObjectProperty>
				// }

				const properties = (path.parent as types.ObjectExpression)
					.properties as Array<types.ObjectProperty>

				// 然后遍历所有当前对象的属性，找到key为 children的，插入一个目标期望代码片段
				if (properties.length) {
					let childrenProperty = properties.find((item) => {
						// 对key需要做断言
						let key = item.key as types.Identifier
						return key.name === 'children'
					})

					console.log(childrenProperty)

					if (childrenProperty) {
						const newNode = createRouteNode()

						let value = childrenProperty.value as types.ArrayExpression
						value.elements.push(newNode)
					}
				}
			}
		}
	}
}

/**
 * 创建节点信息
 */
function createRouteNode() {
	// 手动构建新节点信息
	const newNode = types.objectExpression([
		types.objectProperty(
			types.identifier('path'),
			types.stringLiteral('/addNewUserLog')
		),
		types.objectProperty(
			types.identifier('name'),
			types.stringLiteral('addNewsUserLogName')
		),

		// 创建meta对象信息
		types.objectProperty(
			types.identifier('meta'),
			types.objectExpression([
				types.objectProperty(
					types.identifier('title'),
					types.stringLiteral('新增的节点')
				),

				types.objectProperty(
					types.identifier('hidden'),
					types.booleanLiteral(false)
				),
			])
		),

		types.objectProperty(
			types.identifier('component'),
			types.arrowFunctionExpression(
				[],
				types.importExpression(
					types.stringLiteral('@/views/log-manage/add-new-user-log')
				)
			)
		),
	])

	return newNode
}

const code = generate(ast, {
	jsescOption: {
		minimal: true,
	},
}).code

const dir = path.resolve(__dirname, '../demo/06-1.js')
fs.writeFileSync(dir, code)
